#pragma once

#include "Myriad3D.h"

#define BUFFER_CONSOLE 1
/**
==========================
The Heart of the MyriadEngine
The kernel decides which process runs, and
holds all subsystems
==========================
*/
class Kernel
{
public:
    Kernel(void);

    /** Init the kernel */
    int Init( const std::string &config );
    /** Shutdown all Processes */
    void Shutdown();
    /** Run the kernel */
    void Execute();
    /** Stop Game Loop */
    void StopLoop() { m_quit = true; };

    /** Get the current time */
    float GetTime();
    /** Get the time between last frame and the current one */
    float GetFrameTimeMS();
    /** Timer object */
    Timer& GetTimer() { return m_percisionTimer; };

    /** Console subsystem */
    Console* GetConsole() { return &m_console; };
    /** Cvar System */
    Cvars* GetCvars() { return &m_cvars; };
    /**
     *   Retrieve a subsystem
     */

    /** The Input System */
    IInput* GetInput() { return m_input; };
    /** Sound System */
    ISound* GetSound() { return m_sound; };
    /** The Renderer System */
    RenderManager* GetRenderer() { return m_renderer; };
    /** Scripting Engine System */
    IScriptEngine* GetScriptEngine() { return m_scripter; };
    /** The game System */
    GameManager* GetGame() { return m_game; };

    /** Get the File system */
    IVFSystem*   GetVFileSystem() { return m_fileSystem; };
    ///** Resource Manager System */
    //IResourceManagement* GetResource() { return m_resource; };

    /** Print to console */
    void Printf( const char *s, ... );
    /** Log and print to console */
    void LPrintf( const char *s, ... );


public:
    virtual ~Kernel(void);

private:
    /** Run a Frame */
    void Frame();


    /**
        Flags for initialized subsystems
     */
    enum Subsystem_t 
    {
        SF_INPUT        = (1<<0),
        SF_DEBUG        = (1<<1),
        SF_RENDERER     = (1<<2),
        SF_SCRIPT       = (1<<3),
        SF_SOUND        = (1<<4),
        SF_VFS          = (1<<5)
    };

    /** Init Subsystems */
    void InitVideo();
    void InitInput();
    void InitVFS();
    void InitScript();
    void InitSound();

    // Input System
    IInput*          m_input;
    // Rendering Backend
    RenderManager*   m_renderer;
    // Sound System
    ISound*          m_sound;
    // Scripting System
    IScriptEngine*   m_scripter;
    // Game Management
    GameManager*     m_game;
    //// Resource Management
    //IResourceManagement* m_resource;
    // File system
    IVFSystem*       m_fileSystem;
    // Console - print debug info, exec commands
    Console  m_console;
    // console variables, ingame dynamic variables
    Cvars    m_cvars;

    float   m_lastFrame;
    float   m_delta;
    float   m_nextTick;
    int     m_subsystems;
    // keep the application going
    bool    m_quit;

    bool    m_fixedTimeStep;        // flag for a fixed time step
    // High performance timer
    Timer   m_percisionTimer;

};